package com.zhixi.pattern.important.singletonpattern;

import com.zhixi.pattern.important.singletonpattern.operation.*;
import org.junit.Test;

/**
 * 单例模式
 *
 * 优点：单例模式在内存中只有一个实例，减少了内存开支，特别是一个对象需要频繁的创建，销毁时，
 * 而创建或销毁时性能又无法优化，单例模式的优势就非常明显。
 *
 * 缺点：难扩展，如果需要扩展，则需要修改代码
 *
 * @作者 ShuHaoNan
 * @邮箱 shuhaonan1@gmail.com
 * @时间 2020/11/15 9:32
 */
public class SingletonPattern {

    // 饿汉式（静态变量）
    @Test
    public void instance1() {
        Singleton1 instance1 = Singleton1.getInstance();
        Singleton1 instance2 = Singleton1.getInstance();
        System.out.println(instance1 == instance2);
        System.out.println(instance1.hashCode());
        System.out.println(instance2.hashCode());
    }

    // 饿汉式（静态代码块）
    @Test
    public void instance2() {
        Singleton2 instance1 = Singleton2.getInstance();
        Singleton2 instance2 = Singleton2.getInstance();
        System.out.println(instance1 == instance2);
        System.out.println(instance1.hashCode());
        System.out.println(instance2.hashCode());
    }

    // 懒汉式（单线程）
    @Test
    public void instance3() {
        Singleton3 instance1 = Singleton3.getInstance();
        Singleton3 instance2 = Singleton3.getInstance();
        System.out.println(instance1 == instance2);
        System.out.println(instance1.hashCode());
        System.out.println(instance2.hashCode());
    }

    // 懒汉式（多线程效率低）
    @Test
    public void instance4() {
        Singleton4 instance1 = Singleton4.getInstance();
        Singleton4 instance2 = Singleton4.getInstance();
        System.out.println(instance1 == instance2);
        System.out.println(instance1.hashCode());
        System.out.println(instance2.hashCode());
    }

    // 懒汉式（多线程不安全）
    @Test
    public void instance5() {
        Singleton5 instance1 = Singleton5.getInstance();
        Singleton5 instance2 = Singleton5.getInstance();
        System.out.println(instance1 == instance2);
        System.out.println(instance1.hashCode());
        System.out.println(instance2.hashCode());
    }

    // 双重检查（推荐）
    @Test
    public void instance6() {
        Singleton6 instance1 = Singleton6.getInstance();
        Singleton6 instance2 = Singleton6.getInstance();
        System.out.println(instance1 == instance2);
        System.out.println(instance1.hashCode());
        System.out.println(instance2.hashCode());
    }

    // 静态内部类（推荐）
    @Test
    public void instance7() {
        Singleton7 instance1 = Singleton7.getInstance();
        Singleton7 instance2 = Singleton7.getInstance();
        System.out.println(instance1 == instance2);
        System.out.println(instance1.hashCode());
        System.out.println(instance2.hashCode());
    }

    // 枚举（推荐）
    @Test
    public void instance8() {
        Singleton8 instance1 = Singleton8.INSTANCE;
        Singleton8 instance2 = Singleton8.INSTANCE;
        instance1.ok();
        System.out.println(instance1 == instance2);
        System.out.println(instance1.hashCode());
        System.out.println(instance2.hashCode());
    }

}
